package com.yanqu.road.server.webservice;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.entity.activity.ActivityConditionInfo;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.UserActivityConditionData;
import com.yanqu.road.entity.config.goods.MallInfo;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.mall.LimitBuyResult;
import com.yanqu.road.entity.player.UserAttribute;
import com.yanqu.road.entity.player.UserCard;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.entity.player.UserSubscribe;
import com.yanqu.road.entity.recharge.FindActivityResult;
import com.yanqu.road.entity.recharge.RechargeGain;
import com.yanqu.road.entity.task.UserTaskActive;
import com.yanqu.road.entity.xiaomian.UserXiaoMianData;
import com.yanqu.road.logic.bussiness.player.*;
import com.yanqu.road.logic.bussiness.recharge.RechargeBussiness;
import com.yanqu.road.logic.bussiness.xiaomian.XiaoMianBussiness;
import com.yanqu.road.logic.config.ChannelConfig;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.ActivityModule;
import com.yanqu.road.server.gameplayer.module.player.*;
import com.yanqu.road.server.gameplayer.module.recharge.RechargeGainModule;
import com.yanqu.road.server.gameplayer.module.task.TaskModule;
import com.yanqu.road.server.gameplayer.module.xiaomian.XiaoMianModule;
import com.yanqu.road.server.logic.activity.BaseActivityData;
import com.yanqu.road.server.logic.recharge.RechargeManager;
import com.yanqu.road.server.logic.recharge.limit.MallLimitFactory;
import com.yanqu.road.server.logic.recharge.limit.BaseRMBMallLimit;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.activity.RelationActivityMgr;
import com.yanqu.road.server.manger.activity.unionwar.UnionWarActivityMgr;
import com.yanqu.road.server.manger.config.MallMgr;
import com.yanqu.road.server.manger.config.MallRechargeConfigMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.player.PrivilegeCardMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.LocalDateTimeHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class GamePublicFunction {

    private static Logger logger = LogManager.getLogger(GamePublicFunction.class.getName());
    private static long lastMemoryHighTime = 0L;

    /**
     * 获取元宝可购列表
     */
    public static List<JSONObject> getIngotsMall(long userId, String language, boolean isBackend) {
        List<JSONObject> dataList = new ArrayList<>();
        List<MallInfo> mallInfoList = MallMgr.getMallInfoList(eMallCategory.Ingots.getValue());
        if(!isBackend){
            int channelId = ServerListMgr.getChannelId(GameServer.getInstance().getServerId());
            if(eChannelType.isTwChannel(channelId)) {
                //特殊处理元宝数据  台湾元宝双倍了才返元宝商品信息
                GamePlayer player = GamePlayerMgr.getPlayer(userId);
                if (null != player) {
                    RechargeGainModule rechargeGainModule = player.getModule(RechargeGainModule.class);
                    for (MallInfo mallInfo : mallInfoList) {
                        if (rechargeGainModule.isFirstRechargeDouble(mallInfo, eRechargeGainIndex.ThirdPartyFirstDouble.getValue())) {
                            JSONObject mallObj = parseMallObj(mallInfo, language);
                            long ingotsCount = twGetIngotMallIngotCount(mallInfo);
                            mallObj.put("PRODUCT_DESC", ingotsCount + "元寶");
                            mallObj.put("PRODUCT_TAG", 1);
                            mallObj.put("INGAME_EXTRA_COIN", ingotsCount);
                            mallObj.put("LIMIT_COUNT", Integer.MAX_VALUE);
                            dataList.add(mallObj);
                        }
                    }
                } else {
                    Map<Integer, RechargeGain> rechargeGainMap = RechargeBussiness.getRechargeGainMap(userId);
                    for (MallInfo mallInfo : mallInfoList) {
                        if (isFirstRechargeDouble(rechargeGainMap, mallInfo, eRechargeGainIndex.ThirdPartyFirstDouble.getValue())) {
                            JSONObject mallObj = parseMallObj(mallInfo, language);
                            long ingotsCount = twGetIngotMallIngotCount(mallInfo);
                            mallObj.put("PRODUCT_DESC", ingotsCount + "元寶");
                            mallObj.put("PRODUCT_TAG", 1);
                            mallObj.put("INGAME_EXTRA_COIN", ingotsCount);
                            mallObj.put("LIMIT_COUNT", Integer.MAX_VALUE);
                            dataList.add(mallObj);
                        }
                    }
                }
            }else if(eChannelType.isKrChannel(channelId)){//韩国首充双倍数据
                GamePlayer player = GamePlayerMgr.getPlayer(userId);
                if (null != player) {
                    RechargeGainModule rechargeGainModule = player.getModule(RechargeGainModule.class);
                    for (MallInfo mallInfo : mallInfoList) {
                        JSONObject mallObj = parseMallObj(mallInfo, language);
                        if (rechargeGainModule.isFirstRechargeDouble(mallInfo, eRechargeGainIndex.ThirdPartyFirstDouble.getValue())) {
                            mallObj.put("PRODUCT_TAG", "2배");
                        }
                        mallObj.put("LIMIT_COUNT", Integer.MAX_VALUE);
                        dataList.add(mallObj);
                    }
                } else {
                    Map<Integer, RechargeGain> rechargeGainMap = RechargeBussiness.getRechargeGainMap(userId);
                    for (MallInfo mallInfo : mallInfoList) {
                        JSONObject mallObj = parseMallObj(mallInfo, language);
                        if (isFirstRechargeDouble(rechargeGainMap, mallInfo, eRechargeGainIndex.ThirdPartyFirstDouble.getValue())) {
                            mallObj.put("PRODUCT_TAG", "2배");
                        }
                        mallObj.put("LIMIT_COUNT", Integer.MAX_VALUE);
                        dataList.add(mallObj);
                    }
                }
            }else if(eChannelType.isJapanChannel(channelId)){//日服首充双倍数据
                GamePlayer player = GamePlayerMgr.getPlayer(userId);
                if (null != player) {
                    RechargeGainModule rechargeGainModule = player.getModule(RechargeGainModule.class);
                    for (MallInfo mallInfo : mallInfoList) {
                        JSONObject mallObj = parseMallObj(mallInfo, language);
                        if (rechargeGainModule.isFirstRechargeDouble(mallInfo, eRechargeGainIndex.ThirdPartyFirstDouble.getValue())) {
                            mallObj.put("PRODUCT_TAG", "倍増");
                        }
                        mallObj.put("LIMIT_COUNT", Integer.MAX_VALUE);
                        dataList.add(mallObj);
                    }
                } else {
                    Map<Integer, RechargeGain> rechargeGainMap = RechargeBussiness.getRechargeGainMap(userId);
                    for (MallInfo mallInfo : mallInfoList) {
                        JSONObject mallObj = parseMallObj(mallInfo, language);
                        if (isFirstRechargeDouble(rechargeGainMap, mallInfo, eRechargeGainIndex.ThirdPartyFirstDouble.getValue())) {
                            mallObj.put("PRODUCT_TAG", "倍増");
                        }
                        mallObj.put("LIMIT_COUNT", Integer.MAX_VALUE);
                        dataList.add(mallObj);
                    }
                }
            }else if(eChannelType.isVnChannel(channelId) || eChannelType.isThinChannel(channelId)
                    || eChannelType.isUsChannel(channelId) || eChannelType.isUkChannel(channelId)
            ){//越南或者国际服
                GamePlayer player = GamePlayerMgr.getPlayer(userId);
                if (null != player) {
                    RechargeGainModule rechargeGainModule = player.getModule(RechargeGainModule.class);
                    for (MallInfo mallInfo : mallInfoList) {
                        JSONObject mallObj = parseMallObj(mallInfo, language);
                        if (rechargeGainModule.isFirstRechargeDouble(mallInfo, eRechargeGainIndex.ThirdPartyFirstDouble.getValue())) {
                            mallObj.put("PRODUCT_TAG", "1");
                        }
                        mallObj.put("LIMIT_COUNT", Integer.MAX_VALUE);
                        dataList.add(mallObj);
                    }
                } else {
                    Map<Integer, RechargeGain> rechargeGainMap = RechargeBussiness.getRechargeGainMap(userId);
                    for (MallInfo mallInfo : mallInfoList) {
                        JSONObject mallObj = parseMallObj(mallInfo, language);
                        if (isFirstRechargeDouble(rechargeGainMap, mallInfo, eRechargeGainIndex.ThirdPartyFirstDouble.getValue())) {
                            mallObj.put("PRODUCT_TAG", "1");
                        }
                        mallObj.put("LIMIT_COUNT", Integer.MAX_VALUE);
                        dataList.add(mallObj);
                    }
                }
            }else {
                for (MallInfo mallInfo : mallInfoList) {
                    JSONObject mallObj = parseMallObj(mallInfo, language);
                    mallObj.put("LIMIT_COUNT", Integer.MAX_VALUE);
                    dataList.add(mallObj);
                }
            }
        }else {//直接返回元宝数据
            for (MallInfo mallInfo : mallInfoList) {
                JSONObject mallObj = parseMallObj(mallInfo, language);
                mallObj.put("LIMIT_COUNT", Integer.MAX_VALUE);
                dataList.add(mallObj);
            }
        }
        return dataList;
    }

    /**
     * 是否首充双倍
     * @param dataMap
     * @param mallInfo
     * @param markIndex
     * @return
     */
    private static boolean isFirstRechargeDouble(Map<Integer, RechargeGain> dataMap, MallInfo mallInfo, int markIndex){
        if(!mallInfo.isFirstDouble()){
            return false;
        }
        //判断首充翻倍标识位
        return !dataMap.containsKey(mallInfo.getMallId()) ||
                ((dataMap.get(mallInfo.getMallId()).getState() & ((int) Math.pow(2, markIndex))) == 0);
    }

    /**
     * 获取本地配置可购列表
     */
    public static List<JSONObject> getLocalConfigMall(long userId, int mallCategory, String language) {
        List<JSONObject> dataList = new ArrayList<>();
        List<MallInfo> mallInfoList = MallMgr.getMallInfoList(mallCategory);
        for (MallInfo mallInfo : mallInfoList) {
            if(MallMgr.isSubscribeMall(mallInfo.getMallId())){//订阅商品不可以第三方
                continue;
            }
            BaseRMBMallLimit baseRMBMallLimit = MallLimitFactory.getMallLimit(userId, mallInfo, null);
            if (null != baseRMBMallLimit) {
                if(0 == baseRMBMallLimit.checkMallLimit().getRet()){
                    JSONObject mallObj = parseMallObj(mallInfo, language);
                    mallObj.put("LIMIT_COUNT", 1);
                    dataList.add(mallObj);
                }
            }
        }
        return dataList;
    }

    /**
     * 限时充值活动商品列表
     */
    public static List<JSONObject> getRechargeActivityMall(long userId, String language) {
        List<JSONObject> dataList = new ArrayList<>();
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        if (null == player) {//玩家不在线不能购买
            return dataList;
        }
        //判断系统解锁
        boolean isUnlock = SystemOpenMgr.systemOpen(player, eSystemId.RechargeActivity.getValue());
        if (!isUnlock) {
            return dataList;
        }
        //系统解锁了才加
        List<MallInfo> mallInfoList = MallMgr.getMallInfoList(eMallCategory.RechargeGoods.getValue());
        List<ActivityInfo> activityInfoList = NormalActivityMgr.getRechargeActivityInfoList();
        for (MallInfo mallInfo : mallInfoList) {
            boolean isFind = false;
            for (ActivityInfo activityInfo : activityInfoList) {
                List<ActivityConditionInfo> activityConditionInfoList = NormalActivityMgr.getActivityConditionInfoList(activityInfo.getActivityId());
                if(null != activityConditionInfoList) {
                    for (ActivityConditionInfo activityConditionInfo : activityConditionInfoList) {
                        if ((eGamePlayerEventType.RechargeItem.getValue() == activityConditionInfo.getType() &&
                                activityConditionInfo.getParamList().get(2).compareTo(BigInteger.valueOf(mallInfo.getMallId())) == 0)
                        || newRechargeCanFindMallInfo(activityConditionInfo, mallInfo.getMallId())) {
                            BaseRMBMallLimit baseRMBMallLimit = MallLimitFactory.getMallLimit(userId, mallInfo, activityInfo);
                            if(null != baseRMBMallLimit){
                                LimitBuyResult limitBuyResult = baseRMBMallLimit.checkMallLimit();
                                if(0 == limitBuyResult.getRet()){
                                    if(activityInfo.getType() == eActivityType.NewRechargeActivity.getValue()
                                            && activityInfo.getChildType() == eNewRechargeActivityType.ServerOpenGifts.getValue()
                                    ){
                                        JSONObject mallObj = parseMallObj(mallInfo, language);
                                        mallObj.put("LIMIT_COUNT", limitBuyResult.getLimitCount());
                                        dataList.add(mallObj);
                                    }else {
                                        JSONObject mallObj = parseMallObj(mallInfo, activityConditionInfo, language);
                                        mallObj.put("LIMIT_COUNT", limitBuyResult.getLimitCount());
                                        dataList.add(mallObj);
                                    }
                                    isFind = true;
                                    break;
                                }
                            }
                        }
                    }
                }
                if (isFind) {
                    break;
                }
            }
        }
        return dataList;
    }

    public static boolean newRechargeCanFindMallInfo(ActivityConditionInfo activityConditionInfo, int mallId) {
        ActivityInfo activityInfo = NormalActivityMgr.getActivityInfo(activityConditionInfo.getActivityId());
        if (activityInfo == null) {
            return false;
        }
        if (activityInfo.getType() == eActivityType.NewRechargeActivity.getValue()) {
            int childType = activityInfo.getChildType();
            if (childType == eNewRechargeActivityType.DailyDiscounts.getValue() || childType == eNewRechargeActivityType.WealthGodGifts.getValue()) {
                return activityConditionInfo.getParamList().get(2).compareTo(BigInteger.valueOf(mallId)) == 0;
            } else if (childType == eNewRechargeActivityType.ServerOpenGifts.getValue()) {
                String[] paramStr = activityConditionInfo.getExtendParam().split("\\|");
                for (String param : paramStr) {
                    String[] split = param.split(";");
                    if (Integer.parseInt(split[0]) == mallId) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 活动商品是否可以购买
     */
    public static LimitBuyResult activityMallCanBuy(int activityId, int mallId, long userId) {
        LimitBuyResult limitBuyResult = new LimitBuyResult();
        ActivityInfo activityInfo = NormalActivityMgr.getActivityInfo(activityId);
        if(null == activityInfo){
            activityInfo = RelationActivityMgr.getOpenActivityInfo(activityId);
        }
        if(null == activityInfo) {//不在活动时间
            activityInfo = UnionWarActivityMgr.getOpenActivityInfo(activityId);
        }
        if(null == activityInfo) {
            limitBuyResult.setRet(GameErrorCode.E_PRE_CHARGE_ACTIVITY_NO_IN_TIME);
            return limitBuyResult;
        }

        MallInfo mallInfo = MallMgr.getMallInfoByMallId(mallId);
        if(null == mallInfo){
            limitBuyResult.setRet(GameErrorCode.E_MALL_LIMIT_BUY);
            return limitBuyResult;
        }

        if(mallInfo.getCategory() == eMallCategory.GoldTokeMall.getValue() && mallInfo.getLimitBuyCount() == -1){
            //代金币且不限购商品，不需要玩家登录状态
        }else {
            GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
            if (null == player) {//玩家不在线
                limitBuyResult.setRet(GameErrorCode.E_PRE_CHARGE_PLAYER_OFFLINE);
                return limitBuyResult;
            }
        }

        BaseRMBMallLimit baseRMBMallLimit = MallLimitFactory.getMallLimit(userId, mallInfo, activityInfo);
        if(null == baseRMBMallLimit){
            TempMgr.getLogger().error("MallLimitFactory fail,mallId:{}", mallId);
            limitBuyResult.setRet(GameErrorCode.E_MALL_LIMIT_BUY);
            return limitBuyResult;
        }
        return baseRMBMallLimit.checkMallLimit();
    }

    public static int getSystemIdNewRechargeActivity(int childType) {
        if (childType == eNewRechargeActivityType.DailyDiscounts.getValue()) {
            return eSystemId.DailyDiscount.getValue();
        } else if (childType == eNewRechargeActivityType.WealthGodGifts.getValue()) {
            return eSystemId.WealthGodGifts.getValue();
        } else if (childType == eNewRechargeActivityType.ServerOpenGifts.getValue()) {
            return eSystemId.ServerOpenGifts.getValue();
        }
        return 0;
    }

    /**
     * 获取门客基金购买标识
     */
    public static long getPatronsFundMark(GamePlayer player, long userId) {
        long patronsFundMark;
        if (null != player) {
            patronsFundMark = player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.PatronsFund);
//            if (0 == patronsFundMark) {//找订单里面有没有门客基金的
//                if (player.getModule(RechargeModule.class).hasBuyFund(GameConfig.ACTIVITY_PATRONS_FUND)) {
//                    patronsFundMark = 1;
//                } else {
//                    patronsFundMark = 0;
//                }
//            }
        } else {
            UserAttribute userAttribute = UserAttributeBussiness.getUserAttribute(userId, ePlayerAttrType.PatronsFund);
            if (null == userAttribute) {
                patronsFundMark = 0;
            } else {
                patronsFundMark = userAttribute.getValue();
            }
            if (0 == patronsFundMark) {
                if (RechargeManager.offlineHasBuyFund(userId, GameConfig.ACTIVITY_PATRONS_FUND)) {
                    patronsFundMark = 1;
                } else {
                    patronsFundMark = 0;
                }
            }
        }
        return patronsFundMark;
    }

    /**
     * 获取赚钱基金购买标识
     */
    public static long getEarnSpeedFundMark(GamePlayer player, long userId) {
        long fundMark;
        if (null != player) {
            fundMark = player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.EarnSpeedFund);
//            if (0 == fundMark) {//找订单里面有没有门客基金的
//                if (player.getModule(RechargeModule.class).hasBuyFund(GameConfig.ACTIVITY_EARNMONEY_FUND)) {
//                    fundMark = 1;
//                } else {
//                    fundMark = 0;
//                }
//            }
        } else {
            UserAttribute userAttribute = UserAttributeBussiness.getUserAttribute(userId, ePlayerAttrType.EarnSpeedFund);
            if (null == userAttribute) {
                fundMark = 0;
            } else {
                fundMark = userAttribute.getValue();
            }
            if (0 == fundMark) {
                if (RechargeManager.offlineHasBuyFund(userId, GameConfig.ACTIVITY_EARNMONEY_FUND)) {
                    fundMark = 1;
                } else {
                    fundMark = 0;
                }
            }
        }
        return fundMark;
    }

    /**
     * 获取基金购买标识
     */
    public static long getFundMark(long userId,ePlayerAttrType attrType,int mallId) {
        long fundMark;
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        if (null != player) {
            fundMark = player.getModule(AttributeModule.class).getAttribute(attrType);
//            if (0 == fundMark) {
//                if (player.getModule(RechargeModule.class).hasBuyFund(mallId)) {
//                    fundMark = 1;
//                } else {
//                    fundMark = 0;
//                }
//            }
        } else {
            UserAttribute userAttribute = UserAttributeBussiness.getUserAttribute(userId, attrType);
            if (null == userAttribute) {
                fundMark = 0;
            } else {
                fundMark = userAttribute.getValue();
            }
            if (0 == fundMark) {
                if (RechargeManager.offlineHasBuyFund(userId, mallId)) {
                    fundMark = 1;
                } else {
                    fundMark = 0;
                }
            }
        }
        return fundMark;
    }

    /**
     * 获取精进赚钱基金购买标识
     */
    public static long getEarnSpeedPlusFundMark(GamePlayer player, long userId) {
        long fundMark;
        if (null != player) {
            fundMark = player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.EarnSpeedPlusFound);
//            if (0 == fundMark) {
//                if (player.getModule(RechargeModule.class).hasBuyFund(GameConfig.ACTIVITY_EARNMONEY_PLUS_FUND)) {
//                    fundMark = 1;
//                } else {
//                    fundMark = 0;
//                }
//            }
        } else {
            UserAttribute userAttribute = UserAttributeBussiness.getUserAttribute(userId, ePlayerAttrType.EarnSpeedPlusFound);
            if (null == userAttribute) {
                fundMark = 0;
            } else {
                fundMark = userAttribute.getValue();
            }
            if (0 == fundMark) {
                if (RechargeManager.offlineHasBuyFund(userId, GameConfig.ACTIVITY_EARNMONEY_PLUS_FUND)) {
                    fundMark = 1;
                } else {
                    fundMark = 0;
                }
            }
        }
        return fundMark;
    }

    /**
     * 特权卡是否能够购买
     */
    public static boolean privilegeCardCanBuy(long userId, int cardType) {
        boolean canBuy = false;
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        if (null != player) {
            if (player.getModule(CardModule.class).canBuyCard(cardType)) {
                canBuy = true;
            }
        } else {
            UserCard userCard = UserCardBussiness.getUserCard(userId);
            canBuy = PrivilegeCardMgr.canBuyCard(userCard, cardType);
        }
        return canBuy;
    }

    /**
     * 把商品信息解析成json
     */
    private static JSONObject parseMallObj(MallInfo mallInfo, String language) {
        JSONObject mallObj = new JSONObject();
        mallObj.put("PRODUCT_DESC", MallMgr.getMallName(mallInfo, language));
//        int limitCount = mallInfo.getLimitBuyCount();
//        if(-1 == limitCount){
//            limitCount = 1;
//        }
//        mallObj.put("LIMIT", limitCount);
        mallObj.put("LIMIT", 1);
        mallObj.put("PRODUCT_ID", String.valueOf(mallInfo.getRechargeId()));
        mallObj.put("CP_PRODUCT_ID", String.valueOf(mallInfo.getMallId()));
        mallObj.put("REMARK", String.valueOf(mallInfo.getMallId()));
        return mallObj;
    }

    /**
     * 把商品信息解析成json（限时充值的商品名称比较特殊）
     */
    private static JSONObject parseMallObj(MallInfo mallInfo, ActivityConditionInfo activityConditionInfo, String language) {
        JSONObject mallObj = new JSONObject();
        mallObj.put("PRODUCT_DESC", ServerLanguageMgr.getContent(activityConditionInfo.getDesc(), language));
//        int limitCount = mallInfo.getLimitBuyCount();
//        if(-1 == limitCount){
//            limitCount = 1;
//        }
//        mallObj.put("LIMIT", limitCount);
        mallObj.put("LIMIT", 1);
        mallObj.put("PRODUCT_ID", String.valueOf(mallInfo.getRechargeId()));
        mallObj.put("CP_PRODUCT_ID", String.valueOf(mallInfo.getMallId()));
        mallObj.put("REMARK", String.valueOf(mallInfo.getMallId()));
        return mallObj;
    }

    /**
     * 系统是否解锁
     */
    public static boolean isSystemOpen(long userId, int systemId) {
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        if (null != player) {
            return SystemOpenMgr.systemOpen(player, systemId);
        } else {
            UserInfo userInfo = UserMgr.getUserInfo(userId);
            BigInteger openValue = BigInteger.ZERO;
            if (null != userInfo) {
                openValue = userInfo.getSystemOpenValue();
            }
            return SystemOpenMgr.offlineSystemOpen(openValue, systemId);
        }
    }

    /**
     * 港澳台元宝商品，根据商品金额，转换为元宝数量（金额 * 2）
     * @param mallInfo
     * @return
     */
    public static long twGetIngotMallIngotCount(MallInfo mallInfo){
        if(null == mallInfo){
            return 0;
        }
        long ingotsCount = MallRechargeConfigMgr.getPrice(mallInfo);
//        long ingotsCount = StringUtils.string2longSafe(mallInfo.getPrice(), 0);
        ingotsCount = ingotsCount * 2 / 100;
        return ingotsCount;
    }

    public static JSONObject parseXiaoMianTaskObj(String name, String type, long value){
        JSONObject dataObj = new JSONObject();
        dataObj.put("name", name);
        dataObj.put("type", type);
        dataObj.put("num", value);
        return dataObj;
    }

    public static JSONObject parseDailyTaskObj(String taskId, long value){
        JSONObject dataObj = new JSONObject();
        dataObj.put("task_id", taskId);
        dataObj.put("num", value);
        return dataObj;
    }

    public static String doQueryDailyTaskProgress(String param) {
        JSONObject resultObj = new JSONObject();
        JSONObject paramObj;
        try {
            paramObj = JSONObject.parseObject(param);
        }catch (Exception e){
            resultObj.put("state", 0);
            resultObj.put("msg", "param parse json error,argument error");
            return resultObj.toJSONString();
        }
        long userId = paramObj.getLong("userId");
        long queryTime = paramObj.getLong("time");
        String taskStr = paramObj.getString("task");
        List<String> taskList = JSONObject.parseArray(taskStr, String.class);
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        UserInfo userInfo;
        if(null != player) {
            userInfo = player.getUserInfo();
        }else {
            userInfo = UserMgr.getUserInfo(userId);
        }
        if(null == userInfo){//角色不存在
            resultObj.put("state", 0);
            resultObj.put("msg", "role no exist");
            return resultObj.toJSONString();
        }
        if(!DateHelper.isSameDay(queryTime, System.currentTimeMillis() / 1000)){
            resultObj.put("state", 0);
            resultObj.put("msg", "query time is over now day");
            return resultObj.toJSONString();
        }
        UserXiaoMianData userXiaoMianData = null;
        UserCard userCard = null;
        boolean needQueryCard = false;
        boolean needQueryChatActivity = false;
        boolean needQueryTask = false;
        boolean needQueryXiaoMian = false;
        for(String taskId : taskList){
            if(Objects.equals(ePlatformTask.MONTH_CARD_REWARD.getValue(), taskId) ||
                    Objects.equals(ePlatformTask.YEAR_CARD_REWARD.getValue(), taskId)){
                needQueryCard = true;
            }else if(Objects.equals(ePlatformTask.CHAT_ACTIVITY.getValue(), taskId)){
                needQueryChatActivity = true;
            }else if(Objects.equals(ePlatformTask.DAILY_TASK_ACTIVE.getValue(), taskId)){
                needQueryTask = true;
            }else {
                needQueryXiaoMian = true;
            }
        }

        long chatActivityJoin = 0;
        int taskActive = 0;
        List<ActivityInfo> activityInfoList = null;
        if(needQueryChatActivity){
            activityInfoList = NormalActivityMgr.getChatActivityList();
        }
        if(null != player) {
            if(needQueryCard) {
                userCard = player.getModule(CardModule.class).getUserCard();
            }
            if(needQueryXiaoMian) {
                userXiaoMianData = player.getModule(XiaoMianModule.class).getUserXiaoMianData();
            }
            if(needQueryChatActivity && null != activityInfoList){
                for(ActivityInfo activityInfo : activityInfoList){
                    BaseActivityData baseActivityData = player.getModule(ActivityModule.class).getBaseActivityData(activityInfo.getActivityId());
                    if(null != baseActivityData){
                        for(UserActivityConditionData userActivityConditionData : baseActivityData.getUserActivityConditionDataList()){
                            if(userActivityConditionData.isGetReward()){
                                chatActivityJoin = 1;
                                break;
                            }
                        }
                    }
                }
            }
            if(needQueryTask){
                UserTaskActive userTaskActive = player.getModule(TaskModule.class).getUserTaskActive();
                if(null != userTaskActive){
                    taskActive = userTaskActive.getTaskActive();
                }
            }
        }else {
            if(needQueryCard) {
                userCard = UserCardBussiness.getUserCard(userId);
            }
            if(needQueryXiaoMian) {
                userXiaoMianData = XiaoMianBussiness.getUserXiaoMianData(userId);
                if (null == userXiaoMianData) {
                    userXiaoMianData = new UserXiaoMianData();
                } else {
                    long zeroTime = LocalDateTimeHelper.getZeroTimeTimeStamp() / 1000;
                    if (zeroTime > userXiaoMianData.getResetTime()) {
                        if (zeroTime > userXiaoMianData.getResetTime()) {
                            userXiaoMianData.resetValue();
                            userXiaoMianData.setResetTime(zeroTime);
                        }
                    }
                }
            }
            if(needQueryChatActivity && null != activityInfoList){
                for(ActivityInfo activityInfo : activityInfoList){
                    List<UserActivityConditionData> userActivityConditionDataList = UserActivityBussiness.getUserActivityConditionDataListByUserIdAndType(activityInfo.getActivityId(), userId, eGamePlayerEventType.ChatActivity.getValue());
                    for(UserActivityConditionData userActivityConditionData : userActivityConditionDataList){
                        if(userActivityConditionData.isGetReward()){
                            chatActivityJoin = 1;
                            break;
                        }
                    }
                }
            }
            if(needQueryTask){
                UserTaskActive userTaskActive = UserTaskBussiness.getUserTaskActive(userId);
                if(null != userTaskActive){
                    taskActive = userTaskActive.getTaskActive();
                }
            }
        }

        JSONObject dataObj = new JSONObject();
        dataObj.put("role_id", "" + userInfo.getUserId());
        dataObj.put("role_name", userInfo.getNickName());
        String serverName = ServerListMgr.getServerName(GameServer.getInstance().getServerId(), userInfo.getLanguage());
        dataObj.put("server_name", serverName);
        dataObj.put("datetime", DateHelper.getCurrentDateTimeString("yyyy-MM-dd"));
        JSONArray taskArray = new JSONArray();
        for(String taskId : taskList){
            if(Objects.equals(ePlatformTask.PATRONS_UPGRADE.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getPatronsUpgradeTimes()));
            }else if(Objects.equals(ePlatformTask.BEAUTY_TRYST.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getBeautyTrystTimes()));
            }else if(Objects.equals(ePlatformTask.CHILD_TRAIN.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getChildTrainTimes()));
            }else if(Objects.equals(ePlatformTask.INN_COOK.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getInnCookTimes()));
            }else if(Objects.equals(ePlatformTask.CHILD_MARRIAGE.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getMarriageTimes()));
            }else if(Objects.equals(ePlatformTask.BANQUET_SCORE.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getBanquetScore()));
            }else if(Objects.equals(ePlatformTask.CLINIC_RECEPTION.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getClinicReception()));
            }else if(Objects.equals(ePlatformTask.MONTH_CARD_REWARD.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, PrivilegeCardMgr.isGetCardReward(userCard, eCardType.MonthCard.getValue())));
            }else if(Objects.equals(ePlatformTask.YEAR_CARD_REWARD.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, PrivilegeCardMgr.isGetCardReward(userCard, eCardType.YearCard.getValue())));
            }else if(Objects.equals(ePlatformTask.WINE_SHOP_CALL.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getWineShopCallNumber()));
            }else if(Objects.equals(ePlatformTask.INGOTS_CONSUME.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getIngotsConsume()));
            }else if(Objects.equals(ePlatformTask.CHAT_ACTIVITY.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, chatActivityJoin));
            }else if(Objects.equals(ePlatformTask.CROSS_CHAT.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getCrossChatTimes()));
            }else if(Objects.equals(ePlatformTask.GRAND_CHILD.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getGrandChildCount()));
            }else if(Objects.equals(ePlatformTask.DRUG_STORE_PUBLICITY.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getDrugStorePublicityTimes()));
            }else if(Objects.equals(ePlatformTask.WINERY_MAKE.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getWineryMakeTimes()));
            }else if(Objects.equals(ePlatformTask.DRUG_STORE_BUSINESS.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getDrugStoreBusinessTimes()));
            }else if(Objects.equals(ePlatformTask.GIVE_LIKE.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getGiveLikeTimes()));
            }else if(Objects.equals(ePlatformTask.PASS_ROAD_BOSS_BATTLE.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getPassRoadBossBattleTimes()));
            }else if(Objects.equals(ePlatformTask.TRADE_WAR_KILL_PATRONS.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getTradeWarKillPatronsCount()));
            }else if(Objects.equals(ePlatformTask.JOIN_WASHE_TIME.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getJoinWaSheTimes()));
            }else if(Objects.equals(ePlatformTask.UNION_BARGAIN_TIMES.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, userXiaoMianData.getUnionBargainTimes()));
            }else if(Objects.equals(ePlatformTask.DAILY_TASK_ACTIVE.getValue(), taskId)){
                taskArray.add(GamePublicFunction.parseDailyTaskObj(taskId, taskActive));
            }
        }

        dataObj.put("task", taskArray);
        resultObj.put("state", 1);
        resultObj.put("msg", "success");
        resultObj.put("data", dataObj);
        return resultObj.toJSONString();
    }

    /**
     * 活动商品列表
     */
    public static List<JSONObject> getActivityMall(long userId, String language) {
        List<JSONObject> dataList = new ArrayList<>();
        Map<Integer, Map<Integer, MallInfo>> activityMallInfoMap = ActivityMgr.getAllActivityMallInfoMap();
        for(Map.Entry<Integer, Map<Integer, MallInfo>> dataEntry : activityMallInfoMap.entrySet()){
            for(MallInfo mallInfo : dataEntry.getValue().values()){
                if(mallInfo.getRechargeId() > 0) {//有充值项编号的商品才是
                    try {
                        LimitBuyResult limitBuyResult = activityMallCanBuy(mallInfo.getActivityId(), mallInfo.getMallId(), userId);
                        if (0 == limitBuyResult.getRet()) {
                            JSONObject mallObj = parseMallObj(mallInfo, language);
                            mallObj.put("LIMIT_COUNT", limitBuyResult.getLimitCount());
                            dataList.add(mallObj);
                        }
                    }catch (Exception e) {
                        logger.error("getActivityMall error, userId:{} mallId:{}, e:{}", userId, mallInfo.getMallId(), e);
                    }
                }
            }
        }
        return dataList;
    }

    /**
     * 特惠礼包活动商品
     * @param mallId
     * @return
     */
    public static FindActivityResult findActivityMall(int mallId){
        List<ActivityInfo> activityInfoList = NormalActivityMgr.getRechargeActivityInfoList();
        for (ActivityInfo activityInfo : activityInfoList) {
            List<ActivityConditionInfo> activityConditionInfoList = NormalActivityMgr.getActivityConditionInfoList(activityInfo.getActivityId());
            if(null != activityConditionInfoList) {
                for (ActivityConditionInfo activityConditionInfo : activityConditionInfoList) {
                    if ((eGamePlayerEventType.RechargeItem.getValue() == activityConditionInfo.getType() &&
                            activityConditionInfo.getParamList().get(2).compareTo(BigInteger.valueOf(mallId)) == 0)
                            || GamePublicFunction.newRechargeCanFindMallInfo(activityConditionInfo, mallId)) {
                        return new FindActivityResult(true, activityInfo.getActivityId(), activityConditionInfo);
                    }
                }
            }
        }
        return new FindActivityResult(false, 0, null);
    }

    /**
     * 堆内存超过设置值时，且内存中没有该玩家，无法登录
     *
     * @param userId 可能为0
     * @return 错误码
     */
    public static int loginCheckGameServerMemory(long userId) {

        // 内存里有该玩家：直接登录
        if (userId != 0 && GamePlayerMgr.getOnlinePlayer(userId) != null) {
            return 0;
        }

        // 判断内存过高：提示爆满
        MemoryUsage heapMemoryUsage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
        long percent = heapMemoryUsage.getUsed() * 1000 / heapMemoryUsage.getMax();
        if (percent >= 900) {
            if (System.currentTimeMillis() - lastMemoryHighTime > DateHelper.MINUTE_MILLIONS) {
                lastMemoryHighTime = System.currentTimeMillis();
                logger.error("heap memory : total {}MB, use {}MB, use percent {}%", heapMemoryUsage.getMax() / 1024 / 1024, heapMemoryUsage.getUsed() / 1024 / 1024, percent / 10);
            }
            return GameErrorCode.E_USER_LOGIN_ONLINE_FULL;
        }

        // 内存正常：直接登录
        return 0;
    }

    public static int normalMallCanBuy(int mallId, long userId) {
        MallInfo mallInfo = MallMgr.getMallInfoByMallId(mallId);
        if(null == mallInfo){
            return GameErrorCode.E_MALL_LIMIT_BUY;
        }

        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        if (null == player) {//玩家不在线
            return GameErrorCode.E_PRE_CHARGE_PLAYER_OFFLINE;
        }

        BaseRMBMallLimit baseRMBMallLimit = MallLimitFactory.getMallLimit(userId, mallInfo, null);
        if(null == baseRMBMallLimit){
            TempMgr.getLogger().error("MallLimitFactory fail,mallId:{}", mallId);
            return GameErrorCode.E_MALL_LIMIT_BUY;
        }
        return baseRMBMallLimit.checkMallLimit().getRet();
    }

    /**
    * 描述：周卡是否可以购买
    * 作者：zrq
    * 时间：2023/3/16
    * 参数：

    * 返回值：
    **/
    public static boolean weekCardCanBuy(long userId, int mallId) {
        if(ChannelConfig.WEEK_CARD_SWITCH == 0){
            return false;
        }
        Map<Integer, UserSubscribe> subscribeMap;
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        if (null != player) {
            subscribeMap = player.getModule(RechargeModule.class).getUserSubscribeMap();
        } else {
            subscribeMap = SubscribeBussiness.getUserSubscribeMap(userId);
        }
        return PrivilegeCardMgr.canBuyWeekCard(subscribeMap, mallId);
    }
}
